package com.kitty.game.fight.service;

import com.kitty.game.fight.bean.Fight;
import com.kitty.common.thread.NamedThreadFactory;
import com.kitty.game.fight.task.FightingTask;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

@Component
public class FightExecutorService {

    /**
     * 角色对应战场
     */
    public static final ConcurrentHashMap<Integer, Integer> FIGHT_ROOMS = new ConcurrentHashMap<>();

    /**
     * 角色id_观战对象ID
     */
    public static final ConcurrentHashMap<Integer, Integer> roleId_lookonRoleId = new ConcurrentHashMap<>();
    /**
     * 战场信息
     */
    public static final ConcurrentHashMap<Integer, Fight> FIGHTS = new ConcurrentHashMap<>();
    /**
     * 战场中宠物对应主人id
     */
    public static final ConcurrentHashMap<Integer, Integer> PETID_ROLEID = new ConcurrentHashMap<>();

    /**
     * task worker pool
     */
    private final List<TaskWorker> workerPool = new ArrayList<>();

    private volatile boolean run = true;

    @PostConstruct
    private void init() {
        int size = 9;
        for (int i = 1; i <= size; i++) {
            TaskWorker worker = new TaskWorker(i);
            workerPool.add(worker);
            new NamedThreadFactory("game-fight_" + i).newThread(worker).start();
        }
    }

    public void addFightTask(Fight fight, FightingTask task) {
        int size = workerPool.size();
        int index = fight.getId() % size;
        workerPool.get(index).addTask(task);
    }

    @PreDestroy
    public void shutDown() {
        run = false;
    }

    private class TaskWorker implements Runnable {

        /**
         * worker id
         */
        private int id;
        /**
         * task consumer queue
         */
        private BlockingQueue<FightingTask> taskQueue = new LinkedBlockingQueue<>();

        TaskWorker(int index) {
            this.id = index;
        }

        public void addTask(FightingTask task) {
            this.taskQueue.add(task);
        }

        @Override
        public void run() {
            while (run) {
                try {
                    FightingTask task = taskQueue.take();
                    task.run();
                } catch (Exception e) {

                }
            }

        }
    }
}
